package chatGUI;

import chatController.*;
import chatController.Observer;

import java.awt.event.*;
import java.util.*;

import javax.swing.*;

/**
 * mission: view in the MVC pattern.
 * It organizes the interface with the local user.
 * @author bazile gaye
 */
public class ChatGUI extends Observer implements ActionListener, MouseListener, KeyListener, WindowListener{

	/* Les attributs */
    /**
     * USername of the local user.
     */
    public String loginToSent;
    /**
     * Message sending by the local user.
     */
    public String messageToSend;
    /**
     * Message received by the local user.
     */
    public String messageReceived;
    /**
     * Repertory the differents conversations in differents onglets.
     */
    protected HashMap onglets;
    /**
     * To use the local Calendar and horaries.
     */
    protected Calendar cal = Calendar.getInstance();

	private User localUser;
	private ChatController cc;

	/* Des objets de type frame */
	private ConnectionFrame connection;
	private MainFrame main;
	private ConversationFrame conversation;
	private FileChooser browser;
	private ErrorConnect error;

	/**
	 * Constructor
	 * @param c 
	 */
	public ChatGUI(ChatController c){
		this.cc = c;
		this.localUser = c.getUser();
		this.localUser.attachGUI(this);

		this.connection = new ConnectionFrame();
		this.main = new MainFrame();
		this.conversation = new ConversationFrame();
		this.browser = new FileChooser();
		this.onglets = new HashMap<String,JTextArea>();
		this.error = new ErrorConnect();

		connection.connectButton.addActionListener(this);
		connection.quitButton.addActionListener(this);
		error.okButton.addActionListener(this);
		main.logout.addActionListener(this);
		main.sendbutton.addActionListener(this);
		main.usersList.addMouseListener(this);
		conversation.send.addActionListener(this);
		conversation.textArea.addKeyListener(this);
		conversation.browseButton.addActionListener(this);
		conversation.closeTab.addActionListener(this);
		main.addWindowListener(this);
	}


	/**
	 * Function uses to respond of the actions performed by the local user
	 * login, logout, send message
	 */
	public void actionPerformed(ActionEvent e) {

		/**
		 * Quit the Chat System without logging in
		 */
		if(e.getSource() == connection.quitButton){
			System.exit(0);
		}

		if(e.getSource() == error.okButton){
			error.dispose();
		}

		/**
		 * Log in
		 */
		if(e.getSource() == connection.connectButton){
			if(connection.pseudoText.getText().equals("")){
				error.setVisible(true);
			}
			else{
				//FromUser
				loginToSent = connection.pseudoText.getText();
				localUser.setUsername(loginToSent);
				this.cc.connection(loginToSent);
				//ToUser
				connection.dispose();
				main.setVisible(true);
				main.setTitle("Session de "+loginToSent);
			}
		}

		/**
		 * Log out
		 */
		if(e.getSource() == main.logout){
			//FromUser
			this.cc.deconnection();
			//ToUser
			System.exit(0);
		}

		/**
		 * Send a message to all the online users in the main room
		 */
		if(e.getSource() == main.sendbutton){
			//FromUser
			messageToSend = main.textArea.getText();
			cc.send(messageToSend, true, null);
			//ToUser
			main.textArea.setText(null);
			main.convArea.append("["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+"<"+localUser.getUsername()+ ">"+ messageToSend+'\n');
		}

		/**
		 * Send a unicast message to a remote user in the private room
		 */
		if(e.getSource() == conversation.send){
			//FromUser
			messageToSend = conversation.textArea.getText();
			int index = conversation.ongletChat.getSelectedIndex();
			String remoteUser = conversation.ongletChat.getTitleAt(index);
			cc.send(messageToSend, false, remoteUser);
			//ToUser
			conversation.textArea.setText(null);	
			((JTextArea) this.onglets.get(remoteUser)).append(remoteUser+" says: "+"["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+'\n');
			((JTextArea) this.onglets.get(remoteUser)).append(messageReceived+'\n');
		}

		/**
		 * Close the selected tab
		 */
		if(e.getSource()==conversation.closeTab){
			int index = conversation.ongletChat.getSelectedIndex();
			if(index == 0)
				conversation.dispose();
			else
				conversation.ongletChat.remove(index);

		}
		/**
		 * Browse a file to send to a remote user
		 */
		if(e.getSource() == conversation.browseButton){
			this.browser.setVisible(true);
		}
	}

	/**
	 * Display the users who go online and offline 
	 */
	public void displayOnOff(String remoteUser) {

		main.convArea.append("["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+ messageReceived+'\n');

		Boolean exist = false;
		for(int i=0; i<conversation.ongletChat.getTabCount();i++){
			if(conversation.ongletChat.getTitleAt(i).equals(remoteUser)){
				exist=true;
			}
		}
		if (exist){
			this.conversation.setVisible(true);
			((JTextArea) this.onglets.get(remoteUser)).append("["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+messageReceived+'\n');
		}
	}


	/**
	 * Display an unicast message sent by a remote user in the private room
	 */
	public void afficheMessage(String remoteUser){
		//on vérifie qu'il n'y a pas une conversation en cours

		boolean exist=false;
		for(int i=0; i<conversation.ongletChat.getTabCount();i++){
			if(conversation.ongletChat.getTitleAt(i).equals(remoteUser)){
				exist=true;
			}
		}
		int index = conversation.ongletChat.getSelectedIndex();

		if(exist == false){		
			JTextArea chatArea = new JTextArea();
			chatArea.setEditable(false);
			this.conversation.ongletChat.addTab(remoteUser, chatArea);
			this.conversation.setVisible(true);
			this.onglets.put(remoteUser, chatArea);

			//accéder au JTextArea du bon onglet et afficher
			((JTextArea) this.onglets.get(remoteUser)).append(remoteUser+" says: "+"["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+'\n');
			((JTextArea) this.onglets.get(remoteUser)).append(messageReceived+'\n');
		}
		else{
			this.conversation.setVisible(true);
			((JTextArea) this.onglets.get(remoteUser)).append(remoteUser+" says: "+"["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+'\n');
			((JTextArea) this.onglets.get(remoteUser)).append(messageReceived+'\n');
		}

	}

	/**
	 * Display a broadcast message sent by a remote user in the main room
	 */
	public void afficheBroadcast(){
		main.convArea.append("["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+ messageReceived+'\n');
	}

	/**
	 * Update the list of online users 
	 */
	public void updateList() {
		this.main.usersList.setListData( localUser.afficheListe()); 
		this.main.usersLabel.setText(main.usersList.getModel().getSize() + " online users");     
	}


	/**
	 * Mise à jour de l'état du système. 
	 * (not implemented)
	 */
	@Override
	public void updateState() {}

	/**
	 * Select a user to start a private conversation
	 */
	@Override
	public void mouseClicked(MouseEvent e) {
		JList list = (JList) e.getSource();
		//si on double clique
		if(e.getClickCount()==2){
			//on récupère le nom de l'utilisateur connecté
			int index = list.locationToIndex(e.getPoint());
			String remoteUser = (String) list.getModel().getElementAt(index);
			//on vérifie qu'il n'y a pas une conversation en cours
			boolean exist=false;
			for(int i=0; i<conversation.ongletChat.getTabCount();i++){
				if(conversation.ongletChat.getTitleAt(i)==remoteUser)
					exist=true;
			}
			//si non on crée un onglet
			if(exist==false){
				JTextArea chatArea = new JTextArea();
				chatArea.setEditable(false);
				this.conversation.ongletChat.addTab(remoteUser, chatArea);
				this.conversation.setVisible(true);

				this.onglets.put(remoteUser, chatArea);
			}
			else
				this.conversation.setVisible(true);			
		}
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	/**
	 * Press Enter to send a message
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ENTER){
			//FromUser
			messageToSend = conversation.textArea.getText();
			int index = conversation.ongletChat.getSelectedIndex();
			String remoteUser = conversation.ongletChat.getTitleAt(index);
			cc.send(messageToSend, false, remoteUser);
			//ToUser
			conversation.textArea.setText(null);	
			((JTextArea) this.onglets.get(remoteUser)).append(remoteUser+" says: "+"["+cal.get(Calendar.HOUR_OF_DAY)+"h"+cal.get(Calendar.MINUTE)+"]"+'\n');
			((JTextArea) this.onglets.get(remoteUser)).append(messageReceived+'\n');
		}
	}


	@Override
	public void keyReleased(KeyEvent e) {

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowClosing(WindowEvent arg0) {
		//FromUser
		this.cc.deconnection();
		//ToUser
		connection.setVisible(true);
		main.dispose();
		if (conversation.isShowing() == true)
			conversation.dispose();
	}


	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}


	@Override
	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub

	}

}
